package com.apes.hr.paySupport.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.Employee;
import com.apes.hr.base.model.WorkPost;
import com.apes.hr.base.repository.EmployeeRepository;
import com.apes.hr.paySupport.model.*;
import com.apes.hr.paySupport.repository.SupportApplicationAffirmRepository;
import com.apes.hr.paySupport.repository.SupportApplicationExecutionRepository;
import com.apes.hr.paySupport.repository.SupportApplicationItemRepository;
import com.apes.hr.paySupport.repository.SupportApplicationRepository;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.util.DBObjectUtils;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Title: SupportApplicationAffirmService
 * @Description: 支援确认单
 * @author: ZhengZeXian
 * @create: 2021/4/20 17:26
 */
@Service("hrSupportApplicationAffirmService")
public class SupportApplicationAffirmService extends DomainService {

    @Autowired
    private SupportApplicationAffirmRepository supportApplicationAffirmRepository;
    @Autowired
    private SupportApplicationExecutionRepository supportApplicationExecutionRepository;
    @Autowired
    private SupportApplicationItemRepository supportApplicationItemRepository;
    @Autowired
    private SupportApplicationRepository supportApplicationRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PostRepository postRepository;
    @Autowired
    private PartyRoleRepository partyRoleRepository;
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private EnumerationRepository enumerationRepository;
    @Autowired
    private EmployeeRepository employeeRepository;
    @Autowired
    private StoreRepository storeRepository;

    public SupportApplicationAffirm findById(SimpleRequest request){
        String support_affirm_id = request.get("SUPPORT_AFFIRM_ID");
        return supportApplicationAffirmRepository.findOne(support_affirm_id);
    }

    /**
     * 生成支援确认单 七天为一张单
     */
    public void produceAffirm(SimpleRequest request) throws ParseException {
        //查询所有已经执行未终止且结束日期未到的
        List<SupportApplicationExecution> executions = supportApplicationExecutionRepository.findAllByEndDate();
        //当前时间
        Date date = DateUtil.dateToDate(new Date(),DateUtil.SHOW_DATE_FORMAT);
//        判断当前时间是上午还是下午 结果为“0”是上午 结果为“1”是下午
        GregorianCalendar ca = new GregorianCalendar();
        int i = ca.get(GregorianCalendar.AM_PM);
        String time = i == 0 ? "AM" :"PM";
        //如果开始时间是上午按照七天时间应该是下午 如果开始时间是下午生成按照七天时间应该是上午
        executions.stream().forEach(exec -> {
            SupportApplicationExecution one = supportApplicationExecutionRepository.findOne(exec.getId());
            //如果原来有支援确认单
            if(!one.getSupportApplicationItem().getSupportApplicationAffirms().isEmpty()){
                List<SupportApplicationAffirm> affirms = one.getSupportApplicationItem().getSupportApplicationAffirms();
                affirms = affirms.stream().sorted(Comparator.comparing(SupportApplicationAffirm::getStartDate).reversed()).collect(Collectors.toList());
                SupportApplicationAffirm affirm = affirms.get(0);
                //如果最近的确认的单结束时间是上午，第二张单开始时间从下午开始
                if (affirm.getEndTime().getCode().equals("AM")){
                    //算出相差的天数 减2 开始当天和结束当天不算，后面计算
                    long betweenDays = (DateUtil.dateToDate(exec.getEndDate(),DateUtil.SHOW_DATE_FORMAT).getTime() -
                            DateUtil.dateToDate(affirm.getEndDate(),DateUtil.SHOW_DATE_FORMAT).getTime()) / (1000L*3600L*24L) - 1;
                    double day = calculateDay(betweenDays,"PM",time); //上下午天数计算 得到准确的时间
                    if (day == 7) {
                        Enumeration startTime = enumerationRepository.findByCodeAndValidIsTrue("PM");
                        Enumeration endTime = enumerationRepository.findByCodeAndValidIsTrue(time);
                        //生成确认单 开始时间应该为前面那张单的结束时间的下一个时间段
                        SupportApplicationAffirm insertAffirm = insertAffirm(one,Double.parseDouble("7"), affirm.getEndDate(), startTime, date, endTime);
                        //生成确认单后转OA
                        this.invoke("hr.supportApplicationAffirm.transferOA",insertAffirm);
                    }
                }else {
                    //当前时间 + 1 已有确认单的结束时间为下午 新确认单为开始时间为次日早上
                    Date newDate = DateUtil.add(affirm.getEndDate(), Calendar.DATE, 1);
                    //新开始的时间比执行表里的时间小 说明支援单还没有结束
                    if (DateUtil.dateCompare(newDate,one.getEndDate()) <=0){
                        newDate = DateUtil.dateToDate(newDate,DateUtil.SHOW_DATE_FORMAT);
                        //算出相差的天数 减2 开始当天和结束当天不算，后面计算
                        long betweenDays = (date.getTime() - newDate.getTime()) / (1000L*3600L*24L) - 1;
                        double day = calculateDay(betweenDays,"AM",time); //上下午天数计算 得到准确的时间
                        if (day == 7) {
                            Enumeration startTime = enumerationRepository.findByCodeAndValidIsTrue("AM");
                            Enumeration endTime = enumerationRepository.findByCodeAndValidIsTrue(time);
                            //生成确认单 开始时间应该为前面那张单的结束时间的下一个时间段
                            SupportApplicationAffirm insertAffirm = insertAffirm(one,Double.parseDouble("7"),newDate,startTime, date, endTime);
                            //生成确认单后转OA
                            this.invoke("hr.supportApplicationAffirm.transferOA",insertAffirm);
                        }
                    }
                }

            }else {
                //第一次生成确认单，判断当前时间减去开始时间是不是等于7天如果是就生成
                long betweenDays = (date.getTime() - DateUtil.dateToDate(exec.getStartDate(),DateUtil.SHOW_DATE_FORMAT).getTime()) / (1000L*3600L*24L) - 1;
                double day = calculateDay(betweenDays, one.getSupportApplicationItem().getStartTime().getCode(),time);
                if (day == 7){
                    Enumeration endTime = enumerationRepository.findByCodeAndValidIsTrue(time);
                    SupportApplicationAffirm affirm = insertAffirm
                            (one, Double.parseDouble("7"),one.getSupportApplicationItem().getStartDate(), one.getSupportApplicationItem().getStartTime(),date, endTime);
                    //生成确认单后转OA
                    this.invoke("hr.supportApplicationAffirm.transferOA",affirm);
                }
            }
        });

    }

    /**
     * 生成确认单
     * @return
     */
    public SupportApplicationAffirm insertAffirm(SupportApplicationExecution exec,Double days,Date startDate,Enumeration startTime,Date endDate,Enumeration endTime){
        SupportApplicationAffirm affirm = new SupportApplicationAffirm();
        SupportApplicationItem item = exec.getSupportApplicationItem();
        affirm.setSupportApplicationItem(item);
        affirm.setRequestCode(item.getSupportApplication().getId());
        affirm.setSupportUid(exec.getSupportUid());
        affirm.setState("create");
        affirm.setRequestCode(item.getSupportApplication().getId());
        affirm.setBranch(item.getBranch());
        affirm.setBranchAfter(item.getBranchAfter());
        affirm.setWorkPost(item.getWorkPost());
        affirm.setWorkPostAfter(item.getWorkPostAfter());
        affirm.setJobAfter(item.getJobAfter());
        affirm.setHrTransferKind(item.getHrTransferKind());
        affirm.setActualSupportDays(String.valueOf(days));
        affirm.setNotSupportDays("0");
        affirm.setSupportDays(String.valueOf(days));
        affirm.setSupportAmt(item.getDiscountsAmt() * days);
        affirm.setStartDate(startDate);
        affirm.setStartTime(startTime);
        affirm.setEndDate(endDate);
        affirm.setEndTime(endTime);
        affirm.setConfirmDate(startDate);
        affirm.setBranchOperation(item.getBranchOperation());
        affirm.setBranchAfterOperation(item.getBranchAfterOperation());
        if(item.getBranchFnTag() != null){
            affirm.setBranchFnTag(item.getBranchFnTag());
        }
        Enumeration branchFnTag = item.getBranchFnTag();
        if(branchFnTag == null){
            branchFnTag = new Enumeration();
        }
        double subsidyAmt = getStrategyQty(item.getWorkPostAfter().getId(), item.getJobAfter().getId(), item.getHrTransferKind().getId(), item.getBranchAfterOperation().getId(),branchFnTag.getId());
        affirm.setSubsidyAmt(subsidyAmt * days);
        affirm.setSubsidyAmtDay(subsidyAmt);
        return supportApplicationAffirmRepository.saveAndFlush(affirm);
    }

    /**
     * day 不包含开始当天 和结束当天的纯天数
     * @return
     */
    public Double calculateDay(Long day,String startTime,String endTime){
        Double days = null;
        //算出相差的天数 减2 开始当天和结束当天不算，后面计算
        if (startTime.equals("AM")){
            days = Double.valueOf(day + 1);
        }else if (startTime.equals("PM")){
            days = Double.valueOf(day + 0.5);
        }
        if(endTime.equals("AM")){
            days = Double.valueOf(days + 0.5);
        }else if (endTime.equals("PM")){
            days = Double.valueOf(days + 1);
        }
        return days;
    }

    /**
     * 获取策略金额 收费金额
     * @return
     */
    public double getStrategyQty(String workPostId,String jobId,String hrTransferKind,String operation,String fnTag){
        Map map = MapUtil.mapper(
                "WORK_POST_ID",workPostId, "JOB_ID", jobId, "SUPPORT_TYPE",hrTransferKind, "OPERATION", operation, "FN_TAG", fnTag,"SYS_RQ", new Date(), "conditionStrategyId", "ZY_BT_GZ"
        );
        Object obj = this.invoke("condition.execConditionStrategy", map);
        JSONObject result = new JSONObject(MapUtil.mapped(obj));
        return result.getDoubleValue("T002");
    }

    /**
     *  确认单 转OA
     */
    public Map transferOA(SimpleRequest request){
        SupportApplicationAffirm affirm = request.getO(SupportApplicationAffirm.class);
        //支援人节点 代办人
        User supportUser = userRepository.findByOrigin(affirm.getSupportUid().getOrigin());
        affirm.setSupportOAUid(String.valueOf(supportUser.getId()));

        //岗位分组为店长 直接到督导部
        if (affirm.getWorkPostAfter().getPostGroup().getId().equals("0004")){
            List<User> users = userRepository.findByPost("A0018");
            List<String> candidates = new ArrayList<>();
            if(!users.isEmpty()){
                users.stream().distinct().forEach(user -> {
                    candidates.add(String.valueOf(user.getId()));
                });
            }
            //启用店长审核 流程
            affirm.setOutCandidates(JSONObject.toJSONString(candidates));
            affirm.setSign("dz");
        }else{
            //用人门店
            List<Post> posts = postRepository.findAllByBranchIdAndWorkPostId(affirm.getBranchAfter().getId(), "0000016");
            List<User> agents = new ArrayList<>();
            if (!posts.isEmpty()){
                posts.forEach(post -> {
                    List<User> users = userRepository.findByPost(post.getId());
                    if (!users.isEmpty()) agents.addAll(users);
                });
            }
            if(!agents.isEmpty()){
                List<String> users = new ArrayList<>();
                agents.stream().distinct().forEach(agent -> {
                    users.add(String.valueOf(agent.getId()));
                });
                affirm.setUseCandidates(JSONObject.toJSONString(users));
            }
            SupportApplication supportApplication = supportApplicationRepository.findBySupportApplicationItemId(affirm.getSupportApplicationItem().getId());
            //获取下一个节点的待办人和标识
            Map map = getApproveUserIds(supportApplication);
            affirm.setOutCandidates(map.get("candidates").toString());
            affirm.setSign(map.get("operation").toString());
        }

        affirm.setProcessInitiator(String.valueOf(supportUser.getId()));    //设置OA发起人
        affirm = supportApplicationAffirmRepository.saveAndFlush(affirm);
        return MapUtil.mapped(affirm);
    }

    /**
     * 修改确认单
     */
    public SupportApplicationAffirm update(SimpleRequest request){
        SupportApplicationAffirm affirm = request.getO(SupportApplicationAffirm.class);
        affirm.setSupportAmt(Double.parseDouble(affirm.getActualSupportDays()) * affirm.getSupportAmtDay());
        affirm.setSubsidyAmt(Double.parseDouble(affirm.getActualSupportDays()) * affirm.getSubsidyAmtDay());
        return supportApplicationAffirmRepository.saveAndFlush(affirm);
    }

    /**
     * 支援确认单 确认
     */
    public SupportApplicationAffirm confirm(SimpleRequest request){
        SupportApplicationAffirm affirm = request.getO(SupportApplicationAffirm.class);

        List<Dept> depts = deptRepository.findByBranch(affirm.getBranch());
        if (Objects.isNull(depts)) throw new RuntimeException(affirm.getBranch().getName() + "未找到对应的业务部门，请联系行政！！！");
        List<Dept> deptAfters = deptRepository.findByBranch(affirm.getBranchAfter());
        if (Objects.isNull(deptAfters)) throw new RuntimeException(affirm.getBranchAfter().getName() + "未找到对应的业务部门，请联系行政！！！");

        affirm.setState("confirm");
        affirm.setFinishDate(new Date());

        SupportApplication supportApplication = supportApplicationRepository.findBySupportApplicationItemId(affirm.getSupportApplicationItem().getId());
        List<User> users = userRepository.findByParty(supportApplication.getApproveUid().getParty());
        Employee employee = employeeRepository.findByParty(supportApplication.getApproveUid().getParty());

        //取实际支援天数
        Double realDay = Double.valueOf(affirm.getActualSupportDays());
        //获取出人方公司，运营模式 和用人方公司，运营模式
        PartyRole company = depts.get(0).getCompany();
        PartyRole companyAfter = deptAfters.get(0).getCompany();

        //同公司不生成费用单, 实际支援天数为0不生成费用单
        if (company.getId().equals(companyAfter.getId()) || (realDay == 0)){
            return supportApplicationAffirmRepository.saveAndFlush(affirm);
        }

        String operation = company.getParty().getCorporate().getOperation().getId();
        String operationAfter = companyAfter.getParty().getCorporate().getOperation().getId();
        String remark = "支援申请单号:" +affirm.getSupportApplicationItem().getSupportApplication().getId() +
                " 支援人员:" + affirm.getSupportUid().getName();

        //当“是否收费”为真，但支援类型为"开业支援"或"开业出差支援"时，要根据策略计算出应收的金额生成备注。
        if (!affirm.getSupportApplicationItem().isTollCase() &&
                (affirm.getHrTransferKind().getDescription().equals("开业支援") || affirm.getHrTransferKind().getDescription().equals("开业出差支援"))){
            Enumeration branchFnTag = affirm.getBranchFnTag();
            String fnTag = null;
            if (branchFnTag != null) fnTag = branchFnTag.getId();
            Map map = MapUtil.mapper(
                    "WORK_POST_ID", affirm.getWorkPostAfter().getId(), "JOB_ID",
                    affirm.getJobAfter().getId(), "SUPPORT_TYPE", affirm.getHrTransferKind().getId(),
                    "OPERATION", affirm.getBranchAfterOperation().getId(), "FN_TAG", fnTag, "SYS_RQ",
                    new Date(), "conditionStrategyId", "ZY_SF_GZ"
            );
            Object obj = this.invoke("condition.execConditionStrategy", map);
            JSONObject result = new JSONObject(Objects.requireNonNull(MapUtil.mapped(obj)));
            double t001 = result.getDoubleValue("T001");
            double money = Double.parseDouble(affirm.getActualSupportDays()) * t001;
            //Double money = Double.parseDouble(affirm.getActualSupportDays()) * affirm.getSupportApplicationItem().getTollAmt();
            remark = remark + " ,金额：" + money +" 元（首次开业给予优惠，门店承担费用为0元，门店违约终止合同时，需支付此笔人员成本）";
        }

        //费用单转OA时使用的参数
        Map processMap = MapUtil.mapper(
                "processInitiator", users.isEmpty() ? "1" : String.valueOf(users.get(0).getId()),
                "processInitiatingDepartment", users.isEmpty() ? "1001090000" : employee.getWorkBranch().getId(),
                "processInitiatingPost", users.isEmpty() ? "0000059" : employee.getPost().getId(),
                "userId", users.isEmpty() ? "1" : String.valueOf(users.get(0).getId())
        );

        //计费支援单生成费用单
        if((operation.equals("001072") || operation.equals("001661")) && operationAfter.equals("001073")){
            // 直营或子公司的支援到FN店
            affirm.setExpenseId(createExpense(companyAfter,affirm,remark,"0",true,processMap)); //扣收用人方公司的费用单
            affirm.setGiveExpenseId(createExpense(company,affirm,remark,"1",false,processMap)); //返还出人方公司的费用单
        }else if (operation.equals("001073") && (operationAfter.equals("001072") || operationAfter.equals("001661"))){
            //FN店 支援到 直营 或 子公司
            affirm.setExpenseId(createExpense(companyAfter,affirm,remark,"0",false,processMap)); //扣收用人方公司的费用,直营的不需要转OA
            affirm.setGiveExpenseId(createExpense(company,affirm,remark,"1",true,processMap)); //返还出人方公司的费用单
        }else if (operation.equals("001073") && operationAfter.equals("001073")){
            //FN店支援到FN店
            affirm.setExpenseId(createExpense(companyAfter,affirm,remark,"0",true,processMap)); //扣收用人方公司的费用单
            affirm.setGiveExpenseId(createExpense(company,affirm,remark,"1",true,processMap)); //返还出人方公司的费用单
        }

        return supportApplicationAffirmRepository.saveAndFlush(affirm);
    }

    /**
     * 生成费用单
     * @param company 费用单发生公司
     * @param affirm 计费支援确认单
     * @param remark 备注
     * @param type 类型 0 为扣收 1 为返还
     * @Param needOA 是否需要转OA
     * @param processMap 费用单转OA使用
     * @return 生成的费用单编码
     */
    public String createExpense(PartyRole company,SupportApplicationAffirm affirm,String remark,String type,Boolean needOA,Map processMap){
        // 生成费用单
        List<Map> item = new ArrayList<>();

        //生成的费用单编码
        String expenseId;

        //根据类型 费用单金额 正数为扣收 负数为返还
        Double amount = Objects.equals("0",type) ? affirm.getSupportAmt() : affirm.getSupportAmt() * - 1;

        item.add(MapUtil.mapper(
                "company",  MapUtil.mapped(company),
                "expenseType", MapUtil.mapped(invoke("fn.expenseType.findOne", MapUtil.mapper("id", "B08"))),
                "amount", amount,
                "periodStart", affirm.getStartDate(),
                "periodEnd", affirm.getEndDate(),
                "remark", remark
        ));

        //创建费用单
        Object invoke = invoke("fn.expense.create", MapUtil.mapper("company", MapUtil.mapped(partyRoleRepository.findOne("1007")),
                "expenseItems", item,"creator",affirm.getSupportUid().getParty().getPartyRoles().stream().
                        filter(partyRole -> partyRole.getRole().getId().equals("Employee")).findFirst().get().getId(),"userId",processMap.get("processInitiator")));

        //获取生成的费用单编码
        expenseId = JSONObject.parseObject(JSON.toJSONString(invoke)).getString("id");

        Map rows = MapUtil.mapped(invoke);

        if (needOA) {
            rows.putAll(processMap);
            invoke("fn.expense.apply", rows);             //费用单转OA
        }else {
            invoke("fn.expense.approveBySystem", rows);            //费用单审核
        }

        return expenseId;
    }

    /**
     *  获取待办人列表
     * @param supportApplication
     * @return 代办人json
     */
    public Map getApproveUserIds(SupportApplication supportApplication){
        SupportApplicationDetail detail = supportApplication.getSupportApplicationDetails().get(0);
        String operation = "001072";
        String candidates = "";
        //运营模式(001072:直营;001071:合伙人;001073:赋能店)
        if (detail.getDept() != null){
            operation = deptRepository.findOperationByDept(detail.getDept().getId());
            if (operation.equals("001073")){
                //出人门店已填写并且运营模式是赋能，OA审核人为该门店店长
                List<Post> posts = postRepository.findAllByBranchIdAndWorkPostId(detail.getDept().getBranch().getId(), "0000016");
                List<User> agents = new ArrayList<>();
                if (!posts.isEmpty()){
                    posts.forEach(post -> {
                        List<User> users = userRepository.findByPost(post.getId());
                        if (!users.isEmpty()) agents.addAll(users);
                    });
                }
                if(!agents.isEmpty()){
                    List<String> users = new ArrayList<>();
                    agents.stream().distinct().forEach(agent -> {
                        users.add(String.valueOf(agent.getId()));
                    });
                    candidates = JSONObject.toJSONString(users);
                }
            }
        }
        if (detail.getDept() == null || !operation.equals("001073")){
            //出人门店未填写或者出人门店所属公司的运营模式为直营
            WorkPost workPost = detail.getWorkPost();
            List<User> agents = new ArrayList<>();
            if (workPost.getPostGroup().getId().equals("0005")){
                //支援申请岗位的岗位分组为助理组 下级代办人为财务+督导部
                List<User> users = userRepository.findByPost("A0001");
                List<User> users1 = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
                if (!users1.isEmpty()) agents.addAll(users1);
            }else if(workPost.getPostGroup().getId().equals("0001")){
                //支援申请岗位的岗位分组为美容组 下级代办人为美容技术经理+督导部
                List<User> users = userRepository.findByPost("A0017");
                List<User> users1 = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
                if (!users1.isEmpty()) agents.addAll(users1);
            }else if(workPost.getPostGroup().getId().equals("0002")){
                //支援申请岗位的岗位分组为助理组 下级代办人为财务+督导部
                List<User> users = userRepository.findByPost("A0015");
                List<User> users1 = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
                if (!users1.isEmpty()) agents.addAll(users1);
            }else if(workPost.getPostGroup().getId().equals("0006")){
                //支援申请岗位的岗位分组为服务顾问组 下级代办人为督导部
                List<User> users = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
            }else if(workPost.getPostGroup().getId().equals("0004")){
                //支援申请岗位的岗位分组为店长组 下级代办人为督导部
                List<User> users = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
            }else if(workPost.getPostGroup().getId().equals("0003")){
                //支援申请岗位的岗位分组为钣喷组  下级代办人为钣喷技术经理 督导部
                List<User> users = userRepository.findByPost("A0016");
                List<User> users1 = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
                if (!users1.isEmpty()) agents.addAll(users1);
            }else if(workPost.getPostGroup().getId().equals("0009")){
                //支援申请岗位的岗位 为推广 分组为0009 下级代办人为门管技术中心副总裁 督导部
                List<User> users = userRepository.findByPost("A0014");
                List<User> users1 = userRepository.findByPost("A0018");
                if (!users.isEmpty()) agents.addAll(users);
                if (!users1.isEmpty()) agents.addAll(users1);
            }
            if(!agents.isEmpty()){
                List<String> users = new ArrayList<>();
                agents.stream().distinct().forEach(agent -> {
                    users.add(String.valueOf(agent.getId()));
                });
                candidates = JSONObject.toJSONString(users);
            }
        }
        return MapUtil.mapper(
                "operation",operation,
                "candidates",candidates
        );
    }
}
